(* ast.ml *)
type ty = Int | Void

type unary_op = Plus | Minus | Not
type binary_op =
  | Add | Sub | Mul | Div | Mod
  | Lt | Gt | Le | Ge | Eq | Ne
  | And | Or | Assign

type expr =
  | Number of int
  | Identifier of string
  | UnaryOp of unary_op * expr
  | BinaryOp of binary_op * expr * expr
  | Call of string * expr list
  | Paren of expr

type stmt =
  | Block of stmt list
  | Empty
  | ExprStmt of expr
  | VarDecl of string * expr
  | Assign of string * expr
  | If of expr * stmt * stmt option
  | While of expr * stmt
  | Break
  | Continue
  | Return of expr option

type param = ty * string

type func_def = {
  return_type : ty;
  name : string;
  params : param list;
  body : stmt list;
}

type program = func_def list